/*
 * Created on 26/09/2005
 */
package bancosys.tec.persist.hibernate;

import java.sql.Connection;

import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

import bancosys.tec.persist.authorization.AuthorizationContext;
import bancosys.tec.persist.authorization.AuthorizationManager;
import bancosys.tec.persist.hibernate.page.PagingService;

/**
 * Factory que prove uma Session na particao default.
 * 
 * @author Alexandre
 */
public interface PartitionSessionFactory extends SessionFactory {

    /**
     * Abre uma sessão pura do Hibernate.
     * 
     * @param partition o contexto de autorização.
     * @return a sessão pura.
     */
    Session openPureSession(AuthorizationContext partition);

    /**
     * Devolve uma implementacao de PartitionSession.
     * 
     * @param partition o contexto de autorização.
     * @return uma implementação de PartitionSession
     */
    Session openSession(AuthorizationContext partition);

    /**
     * Devolve uma implementacao de PartitionSession.
     * 
     * @param partition o contexto de autorização.
     * @param conn uma conexão
     * @return uma implementação de PartitionSession.
     */
    Session openSession(AuthorizationContext partition, Connection conn);

    /**
     * Devolve uma implementacao de PartitionSession
     * 
     * @param partition o contexto de autorização.
     * @param conn uma conexão.
     * @param interceptor um interceptador.
     * @return uma implementação de PartitionSession.
     */
    Session openSession(AuthorizationContext partition, Connection conn, Interceptor interceptor);

    /**
     * Devolve uma implementacao de PartitionSession.
     * 
     * @param partition o contexto de autorização.
     * @param interceptor um interceptador.
     * @return uma implementação de PartitionSession.
     */
    Session openSession(AuthorizationContext partition, Interceptor interceptor);

    /**
     * Retorna um SessionFactory puro do Hibernate.
     * 
     * @param partition o contexto de autorização.
     * @return um SessionFactory puro do Hibernate.
     */
    SessionFactory getPureSessionFactory(AuthorizationContext partition);

    /**
     * Devolve o BOAuthorizationManager.
     * 
     * @return o BOAuthorizationManager.
     */
    AuthorizationManager getBoAuthorizationManager();

    /**
     * Para essa thread, execute openSession na partição especificada.
     * 
     * @param partition o contexto de autorização.
     */
    void setThreadPartition(AuthorizationContext partition);

    /**
     * Troca o contexto de autorização de uma sessão.
     * 
     * @param session sessão.
     * @param context contexto de autorização.
     * @return devolve a partição anterior.
     */
    AuthorizationContext changeSessionAuthorizationContext(org.hibernate.Session session, AuthorizationContext context);

    /**
     * Devolve o contexto de autorização da thread.
     * 
     * @return o contexto de autorização da thread.
     */
    AuthorizationContext getThreadPartition();

    /**
     * Para a thread corrente, retorne sempre a sessão pura.
     * <p>
     * openSession == openPureSession.
     * 
     * @param pureSessionOnly <code>true</code> caso use sempre a sessão pura, <code>false</code> caso contrário.
     */
    void setThreadPureSessionOnly(boolean pureSessionOnly);

    /**
     * A thread corrente está sempre em sessão pura?
     * 
     * @return <code>true</code> caso use sempre a sessão pura, <code>false</code> caso contrário.
     */
    boolean isThreadPureSessionOnly();

    /**
     * Restaura o contexto de autorização para a thread corrente.
     */
    void restoreThreadPartition();

    /**
     * Devolve a configuração.
     * 
     * @return a configuração.
     */
    Configuration getConfiguration();

    /**
     * Devolve o serviço de paginação ou <code>null</code> se ele não estiver disponível.
     * 
     * @return o serviço de paginação ou <code>null</code> se ele não estiver disponível.
     */
    PagingService getPagingService();

    /**
     * Define o pagingService.
     * 
     * @param pagingService o pagingService a ser usado.
     */
    void setPagingService(PagingService pagingService);
}
